package sivin.uikit.adapter2

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding

open class CommonAdapter<E> : RecyclerView.Adapter<XViewHolder<ViewBinding>>() {

    private lateinit var dataList: List<E>

    private val mItemViewDelegateManager = ItemViewDelegateManager<E, ViewBinding>()

    override fun getItemViewType(position: Int): Int {
        if (!useItemViewDelegateManager()) {
            return super.getItemViewType(position)
        }
        return mItemViewDelegateManager.getItemViewType(dataList[position], position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): XViewHolder<ViewBinding> {
        val itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(viewType)
        val binding =
            itemViewDelegate.bindingInflate(LayoutInflater.from(parent.context), parent, false)
        val holder = itemViewDelegate.onCreateViewHolder(binding, viewType)
        itemViewDelegate.onViewHolderCreate(holder)
        return holder
    }

    override fun getItemCount(): Int {
        return dataList.size
    }

    override fun onBindViewHolder(holder: XViewHolder<ViewBinding>, position: Int) {
        mItemViewDelegateManager.bindData(holder.viewType, holder, dataList[position], position)
    }

    override fun onViewRecycled(holder: XViewHolder<ViewBinding>) {
        super.onViewRecycled(holder)
        val position = holder.bindingAdapterPosition
        if (position == RecyclerView.NO_POSITION) {
            return
        }
        mItemViewDelegateManager.onRecycleItemView(
            holder, dataList[position], position
        )
    }

    override fun onViewAttachedToWindow(holder: XViewHolder<ViewBinding>) {
        super.onViewAttachedToWindow(holder)
        val position = holder.bindingAdapterPosition
        if (position == RecyclerView.NO_POSITION) {
            return
        }
        mItemViewDelegateManager.onViewAttachedToWindow(
            holder, dataList[position], position
        )
    }

    override fun onViewDetachedFromWindow(holder: XViewHolder<ViewBinding>) {
        super.onViewDetachedFromWindow(holder)
        val position = holder.bindingAdapterPosition
        if (position == RecyclerView.NO_POSITION) {
            return
        }
        mItemViewDelegateManager.onViewDetachedFromWindow(
            holder, dataList[position], position
        )
    }

    private fun useItemViewDelegateManager(): Boolean {
        return mItemViewDelegateManager.getItemViewDelegateCount() > 0
    }

    fun setDataList(dataList: List<E>) {
        this.dataList = dataList
    }

    @Suppress("UNCHECKED_CAST")
    fun <Binding : ViewBinding> addItemViewDelegate(itemViewDelegate: Any) {
        mItemViewDelegateManager.addDelegate(itemViewDelegate as ItemViewDelegate3<E, ViewBinding, XViewHolder<ViewBinding>>)
    }

    @Suppress("UNCHECKED_CAST", "UNUSED")
    fun <Binding : ViewBinding, VH : XViewHolder<Binding>> addItemViewDelegate(itemViewDelegate: ItemViewDelegate3<E, Binding, VH>) {
        mItemViewDelegateManager.addDelegate(itemViewDelegate as ItemViewDelegate3<E, ViewBinding, XViewHolder<ViewBinding>>)
    }
}

open class XViewHolder<Binding : ViewBinding>(val binding: Binding, val viewType: Int) :
    RecyclerView.ViewHolder(binding.root)